package org.sistema.pgfx.entidad;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.pgfx.ejbModule.entidad.BaseEntity;

@Entity
@Table(name = "funcionalidades")
public class Funcionalidad extends BaseEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	@Column(name = "fun_codigo", unique = true, nullable = false)
	private Integer codigo;

	@Column(name = "fun_nombre", length = 100)
	private String nombre;

	@Column(name = "fun_observacion", length = 100)
	private String observacion;

	@Column(name = "fun_menu", length = 1)
	private Integer menu;	//Si es 1, indica que las funcionalidades son del menu, no del treeview.

	@Column(name = "fun_comando", length = 100)
	private String comando;

	@ManyToOne
	@JoinColumn(name = "fun_funcionalidad", nullable = true)
	private Funcionalidad funcionalidad;

	@OneToMany(mappedBy = "funcionalidad", fetch=FetchType.EAGER, cascade = CascadeType.ALL, targetEntity=Funcionalidad.class)
	@OrderBy("funcionalidad, orden ASC")
	private Set<Funcionalidad> funcionalidades;
	
	@Column(name = "fun_orden")
	private Integer orden;

	@Column(name = "fun_isfuncionalidad")
	private Integer isFuncionalidad;
	
	@Column(name = "fun_tag")
	private String tag;
	
	@Column(name = "fun_is_Beta")
	private Integer isBeta;

	@Transient
	private boolean checked;

	@Transient
	private boolean hidden;

	public Funcionalidad(){
	}
	public Integer getCodigo() {
		return codigo;
	}
	public String getNombre() {
		return nombre;
	}
	public String getObservacion() {
		return observacion;
	}
	public void setCodigo(Integer codigo) {
		this.codigo = codigo;
	}
	public void setNombre(String descripcion) {
		this.nombre = descripcion;
	}
	public void setObservacion(String observacion) {
		this.observacion = observacion;
	}
	public Funcionalidad getFuncionalidad() {
		return funcionalidad;
	}
	public void setFuncionalidad(Funcionalidad funcionalidad) {
		this.funcionalidad = funcionalidad;
	}
	public Set<Funcionalidad> getFuncionalidades() {
		return funcionalidades;
	}
	
	public void setFuncionalidades(Set<Funcionalidad> funcionalidades) {
		this.funcionalidades = funcionalidades;
	}

	public Integer getOrden() {
		return orden;
	}

	public void setOrden(Integer orden) {
		this.orden = orden;
	}

	public Integer getMenu() {
		return menu;
	}

	public void setMenu(Integer menu) {
		this.menu = menu;
	}

	public String getComando() {
		return comando;
	}

	public void setComando(String comando) {
		this.comando = comando;
	}

	public Integer getIsFuncionalidad() {
		return isFuncionalidad;
	}

	public void setIsFuncionalidad(Integer isFuncionalidad) {
		this.isFuncionalidad = isFuncionalidad;
	}

	@Transient
	public String toStringPadresJSON() {
		boolean leaf = false;
		//boolean leaf = (isFuncionalidad==1 ? true : false);
		String retorno = "";
		retorno += "{";
		retorno += "id : " + codigo + ", ";
		retorno += "idParent : null, ";
		retorno += "text : '" + nombre + "', ";
		retorno += "description : '" + observacion + "', ";
		retorno += "orderNumber : " + orden + ", ";
		retorno += "menu : " + menu + ", ";
		retorno += "comando : \"" + comando + "\", ";
		retorno += "tag : \"" + tag + "\", ";
		retorno += "expanded : true, ";
		retorno += "leaf : " + leaf + ", ";
		retorno += "isFuncionalidad : " + isFuncionalidad + "";
		
		retorno += "}";
		return retorno;
	}
	
	@Override
	public String toString() {
		boolean leaf = true;
		//funcionalidades.size();
		if (getFuncionalidades() != null && getFuncionalidades().size() > 0){
			leaf = false;
		}
		//boolean leaf = (isFuncionalidad==1 ? true : false);
		String retorno = "";
		retorno += "{";
		retorno += "id : " + codigo + ", ";
		retorno += "idParent : " + ( (funcionalidad!=null && funcionalidad.codigo!=null) ? funcionalidad.codigo : "null") + ", ";
		retorno += "text : '" + nombre + "', ";
		retorno += "description : '" + observacion + "', ";
		retorno += "orderNumber : " + orden + ", ";
		retorno += "menu : " + menu + ", ";
		retorno += "comando : \"" + comando + "\", ";
		retorno += "tag : \"" + tag + "\", ";
		retorno += "expanded : true, ";
		retorno += "leaf : " + leaf + ", ";
//		retorno += "checked : false, ";
		retorno += "hidden : " + hidden + ", ";
		retorno += "isFuncionalidad : " + isFuncionalidad + "";
		
		
		if (funcionalidades != null && funcionalidades.size() > 0){
			retorno += ", ";
			retorno += "children : [";	
			for (Funcionalidad childdren : funcionalidades) {
				retorno += "" + childdren.toString() + ",";	
			}
			retorno += "]";				
		}

		retorno += "}";
		return retorno;
	}
	
	public String toStringReal() {
		boolean leaf = true;
		if (getFuncionalidades() != null && getFuncionalidades().size() > 0){
			leaf = false;
		}
		//boolean leaf = (isFuncionalidad==1 ? true : false);
		String retorno = "";
		retorno += "{";
		retorno += "codigo : " + codigo + ", ";
		retorno += "funcionalidad : {codigo:" + ( (funcionalidad!=null && funcionalidad.codigo!=null) ? funcionalidad.codigo : "null") + ", nombre:'" + ( (funcionalidad!=null && funcionalidad.nombre!=null) ? funcionalidad.nombre : "null") + "'}, ";
		retorno += "nombre : '" + nombre + "', ";
		retorno += "observacion : '" + observacion + "', ";
		retorno += "orden : " + orden + ", ";
		retorno += "menu : " + menu + ", ";
		retorno += "comando : \"" + (comando==null?"":comando) + "\", ";
		retorno += "tag : \"" + tag + "\", ";
		retorno += "expanded : true, ";
		retorno += "leaf : " + leaf + ", ";
//		retorno += "checked : false, ";
		retorno += "hidden : " + hidden + ", ";
		retorno += "isFuncionalidad : " + isFuncionalidad + "";
		
		
		if (funcionalidades != null && funcionalidades.size() > 0){
			retorno += ", ";
			retorno += "children : [";	
			for (Funcionalidad childdren : funcionalidades) {
				retorno += "" + childdren.toStringReal() + ",";	
			}
			retorno += "]";				
		}

		retorno += "}";
		return retorno;
	}
	@Transient
	public String toString( List<NivelFuncionalidad> nivelesFuncionalidades ) {
		boolean leaf = true;
		//funcionalidades.size();
		if (getFuncionalidades() != null && getFuncionalidades().size() > 0){
			leaf = false;
		}
		//boolean leaf = (isFuncionalidad==1 ? true : false);
		hidden = true; //Valor por defecto, sigue la tecnica del minimo privilegio, ninguna funcionalidad debe mostrar si 
						//un usuario no es administrador..
		String retorno = "";
		retorno += "{";
		retorno += "id : " + codigo + ", ";
		retorno += "idParent : " + ( (funcionalidad!=null && funcionalidad.codigo!=null) ? funcionalidad.codigo : "null") + ", ";
		retorno += "text : '" + nombre + "', ";
		retorno += "description : '" + observacion + "', ";
		retorno += "orderNumber : " + orden + ", ";
		retorno += "menu : " + menu + ", ";
		retorno += "comando : \"" + comando + "\", ";
		retorno += "tag : \"" + tag + "\", ";
		retorno += "expanded : true, ";
		retorno += "leaf : " + leaf + ", ";
//		retorno += "checked : false, ";
		retorno += "hidden : " + hidden + ", ";
		retorno += "isFuncionalidad : " + isFuncionalidad + "";
		
		//Codigo agregado al "toString() normal".
		//Verificar la lista de funcionalidaes padres, para asignar hidden = false, ya que si se muestra el hijo, se debe mostrar
		//tambien el padre donde este hijo se encuentra.
		//Preparado para 4 niveles, si se crean funcionalidades de mas nivel, esta codificacion hay que aumentar.
		for (NivelFuncionalidad nivelFuncionalidad : nivelesFuncionalidades) {
			if (this.getCodigo().equals(  nivelFuncionalidad.getId().getFuncionalidad()  )) {
				System.out.println( "Esta funcionalidad debe ser habilitada  " + this.getCodigo());
				this.setHidden(false);
				if (this.getFuncionalidad() != null){
					this.getFuncionalidad().setHidden(false);
					if (this.getFuncionalidad().getFuncionalidad() != null){
						this.getFuncionalidad().getFuncionalidad().setHidden(false);
						if (this.getFuncionalidad().getFuncionalidad().getFuncionalidad() != null){
							this.getFuncionalidad().getFuncionalidad().getFuncionalidad().setHidden(false);
						}
					}
				}
			}
		}
		// 
		if (funcionalidades != null && funcionalidades.size() > 0){
			retorno += ", ";
			retorno += "children : [";
			for (Funcionalidad childdren : funcionalidades) {
				retorno += "" + childdren.toString(nivelesFuncionalidades) + ",";	
			}
			retorno += "]";				
		}

		retorno += "}";
		return retorno;
	}
	public boolean isChecked() {
		return checked;
	}
	public void setChecked(boolean checked) {
		this.checked = checked;
	}
	@Transient
	public String toStringChecked() {
		boolean leaf = true;
		//funcionalidades.size();
		if (getFuncionalidades() != null && getFuncionalidades().size() > 0){
			leaf = false;
		}
		//boolean leaf = (isFuncionalidad==1 ? true : false);
		String retorno = "";
		retorno += "{";
		retorno += "id : " + codigo + ", ";
		retorno += "idParent : " + ( (funcionalidad!=null && funcionalidad.codigo!=null) ? funcionalidad.codigo : "null") + ", ";
		retorno += "text : '" + nombre + "', ";
		retorno += "description : '" + observacion + "', ";
		retorno += "orderNumber : " + orden + ", ";
		retorno += "menu : " + menu + ", ";
		retorno += "comando : \"" + comando + "\", ";
		retorno += "tag : \"" + tag + "\", ";
		retorno += "expanded : true, ";
		retorno += "hidden : " + hidden + ", ";
		retorno += "leaf : " + leaf + ", ";
		if (leaf)
			retorno += "checked : " + isChecked() + ", ";
		retorno += "isFuncionalidad : " + isFuncionalidad + "";
		
		if (funcionalidades != null && funcionalidades.size() > 0){
			retorno += ", ";
			retorno += "children : [";	
			for (Funcionalidad childdren : funcionalidades) {
				retorno += "" + childdren.toStringChecked() + ",";	
			}

/*			try {
				FuncionalidadFacadeRemote ppu = (FuncionalidadFacadeRemote) FuncionalidadFacade.getRemoteHome(Funcionalidad.class);
				List<FuncionalidadEvento> funEvento =  ppu.getEventos(this);
				if (funEvento != null && funEvento.size()>0){
					retorno += "children : [";
					
					retorno += "]";				
				}
				
			} catch (Exception e) {
				// TODO: handle exception
			}
*/
			
			retorno += "]";				
		}

		

		retorno += "}";
		return retorno;
	}
	public boolean isHidden() {
		return hidden;
	}
	public void setHidden(boolean hidden) {
		this.hidden = hidden;
	}
	public String getTag() {
		return tag;
	}
	public void setTag(String tag) {
		this.tag = tag;
	}
	public Integer getIsBeta() {
		return isBeta;
	}
	public void setIsBeta(Integer isBeta) {
		this.isBeta = isBeta;
	}


}